package auth

import (
	"crypto/rand"
	"encoding/base64"
	"io"
	"log"
	"time"

	"rtsp1/user/database"
)

const (
	DBURL = "username:password@tcp([ip]:[port])/table"

	ExpireHour = 1
)

var users userList
var db database.DB

func init() {
	users = NewUserList()
	mysql := database.MySql(DBURL)
	db = &mysql
}

func creatToken() string {
	b := make([]byte, 32)
	if _, err := io.ReadFull(rand.Reader, b); err != nil {
		return ""
	}
	return base64.URLEncoding.EncodeToString(b)
}

func Login(name string, password string) (token session, err error) {
	if !db.Open() {
		err = ErrServer
		return
	}
	defer db.Close()

	pwd, err := db.GetPassword(name)
	if err != nil {
		log.Println("GetPass:", err.Error())
		err = ErrServer
		return
	}

	if password != pwd {
		err = ErrLogin
		return
	}
	t := creatToken()
	token = session{
		Token: t,
	}
	token.Delay(time.Hour * ExpireHour)

	authority, err := db.GetAuthority(name)
	if err != nil {
		log.Println("GetAuthority:", err.Error())
		err = ErrServer
		return
	}

	users.Add(token, name, authority)

	return
}

func IsLogin(token string) (bool, error) {
	if users.IsHave(token) {
		info, _ := users.Get(token)
		if info.Token.Expire() {
			users.Remove(token)
			return false, ErrTokenExpire
		}
		return true, nil
	}
	return false, nil
}

func Logout(token string) {
	if users.IsHave(token) {
		users.Remove(token)
	}
	return
}

func Authority(token string) (int, error) {
	if users.IsHave(token) {
		info, _ := users.Get(token)
		if info.Token.Expire() {
			users.Remove(token)
			return -1, ErrTokenExpire
		}
		authority := info.Authority
		return authority, nil
	}
	return -1, ErrNotExist
}
